﻿using Microsoft.AspNetCore.Mvc.RazorPages;
using NPOI.SS.Formula.Functions;
using ReceiptPrint.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlTypes;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using WalkingTec.Mvvm.Core;

namespace ReceiptPrint
{
    public class ReportHelper
    {
        private const float ScaleFactor = 203 / 96f;
        public const string FontName = "Courier New";
        private const int LineLen = 34;
        public const string Head = "F & S Supermarkt Hob.\r\nCerme Food B.V.\r\nHoboemastraat 173\r\n2526 JJ Den Haag\r\nBTW nr:NLB 13279021";

        public const string Head2 =  "KASSABON Nr 2101402220    Kassa  2\r\n" +
                                     "14/10/2022   19:33        E. Narin";

        public const string Footer = "TOT ZIENS      Tel: 070-3887800\r\n" +
                                     "Ma t/m Za 08:00-20:00Zo10:00-18:00\r\n" +
                                     "Zuivel,Dieovries, Actie artikelen\r\n" +
                                     "ruilen wij niet!";

        public static string GetLine()
        {
            return "".PadRight(LineLen,'-');
        }
        public static string GetERU()
        {
            return "ERU".PadLeft(LineLen - 1, ' ');
        }
        public static string GetOtherERU(string left, float money)
        {
            return "".PadRight(9, ' ') + left + money.ToString("#0.00").PadLeft(LineLen - 13 - left.Length, ' ') + " ERU";
        }

        public static string GetReceiptInfo(List<ReceiptInfo> receipts)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (var info in receipts)
            {
                var price = GetPrice(info.Price);
                var money = (price * info.Number).ToString("#0.00");
                if (info.Number != 1f)
                {
                    var number = info.Number.ToString("#0.00");
                    var arr = number.Split(".");
                    if (arr[1] == "00")
                    {
                        number = arr[0];
                    }
                    var mx = $"{number} × {price} = "; 
                    
                    var tempName = info.Name;
                    var len = 25;
                    if (tempName.Length > len)
                    {
                       
                        do
                        {
                            stringBuilder.AppendLine($"{tempName.Substring(0, len).PadLeft(len, ' ')}");
                            tempName = tempName.Substring(len);
                        }
                        while (tempName.Length > len);
                        stringBuilder.AppendLine($"{tempName.PadLeft(len, ' ')}");
                    }
                    else
                    {
                        stringBuilder.AppendLine($"{info.Name}");
                    }
                       

                    stringBuilder.AppendLine($"{mx}{GetEmpty(5)}{money} {GetTax(info.Tax,true)}".PadLeft(LineLen,' '));
                }
                else
                {
                    var num = 31 - info.Name.Length - money.Length;
                    if (num > 0)
                    {
                        stringBuilder.AppendLine($"{info.Name}{GetEmpty(num)}{money} {GetTax(info.Tax)}");
                    }
                    else
                    {
                        var tempName = info.Name;

                        var len = 31 - money.Length - 1;
                        do
                        {
                            stringBuilder.AppendLine($"{tempName.Substring(0, len).PadLeft(len, ' ')}");
                            tempName = tempName.Substring(len);
                        }
                        while (tempName.Length > len);

                        stringBuilder.AppendLine($"{tempName.PadLeft(len, ' ')} {money} {GetTax(info.Tax)}");
                    }
                }
            }
            stringBuilder.AppendLine(GetLine());
            var allMoney = receipts.Sum(x=> GetPrice( x.Price) * x.Number);
            stringBuilder.AppendLine(GetOtherERU("TOTAAL Incl:", allMoney));
            return stringBuilder.ToString();
        }

        public static string GetTax(Tax tax,bool addRightEmpty = false)
        {
           return $"{(tax == Tax.Zero ? "" : tax.ToString())}{(addRightEmpty ? " ":"")}";
        }
        public static float GetRealMoney(float money, int tax)
        {
            return money / (1 + (tax / 100f));
        }
        public static float GetPrice(float money) 
        {
            return (float)Math.Round((money / 7.65), 2) ;
        }
        public static string GetBelastingtariefAndMoney(float money, List<ReceiptInfo> receipts)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendLine($"Belastingtarief{GetEmpty(6)}BTW{GetEmpty(5)}Incl.");
            var leftLen = 16;
            var dic = receipts.GroupBy(x => x.Tax).Select(x => new { Tax = x.Key, Money = x.Sum(y => GetPrice(y.Price) * y.Number) }).ToDictionary(k=>k.Tax,v=>v.Money);
            float[] sum = new float[] { 0f,0f,0f };
            foreach (var kvp in dic) 
            {
                
                var tax = (int)kvp.Key;
                var m0 = GetRealMoney(kvp.Value, tax);
                var m1 = kvp.Value - m0;

                sum[0] = sum[0] + m0;
                sum[1] = sum[1] + m1;
                sum[2] = sum[2] + kvp.Value;
                var strTax = $"{GetTax(kvp.Key)} {tax}%";
                var strM0 = m0.ToString("#0.00");
                string line = $"{strTax}{GetEmpty(leftLen - strTax.Length - strM0.Length)}{strM0}{GetEmpty(5)}";
                var strM1 = m1.ToString("#0.00");
                var strMoney = kvp.Value.ToString("#0.00");

                stringBuilder.AppendLine($"{line}{strM1}{GetEmpty(13 - strM1.Length - strMoney.Length)}{strMoney}");
            }
            var total = "Totaal";
            var strSum0 = sum[0].ToString("#0.00");
            var strSum1 = sum[1].ToString("#0.00");
            var strSum2 = sum[2].ToString("#0.00");
            stringBuilder.AppendLine($"{total}{GetEmpty(leftLen - total.Length - strSum2.Length)}{strSum0}{GetEmpty(5)}{strSum1}{GetEmpty(13 - strSum1.Length - strSum2.Length)}{strSum2}");
            stringBuilder.AppendLine(GetLine());
            stringBuilder.AppendLine(GetOtherERU("Kontant",money));
            stringBuilder.AppendLine(GetOtherERU("Teruggave:", money - sum[2]));


            return stringBuilder.ToString();
        }
        public static string GetEmpty(int num)
        {
            if (num < 0)
            {
                return string.Empty;
            }
            return "".PadLeft(num,' ');
        }
        private static string FindReportsFolder(string startDir)
        {
            string directory = Path.Combine(startDir, "Reports");
            if (Directory.Exists(directory))
                return directory;

            for (int i = 0; i < 6; i++)
            {
                startDir = Path.Combine(startDir, "..");
                directory = Path.Combine(startDir, "Reports");
                if (Directory.Exists(directory))
                    return directory;
            }

            throw new Exception("Demos/Reports directory is not found");
        }

        public static void Print(long id,string text)
        {
            var reportsDirectory = FindReportsFolder(Environment.CurrentDirectory);
            var doc = new PrintDocument { DocumentName = $"小票{id}", PrintController = new StandardPrintController() };
            doc.DefaultPageSettings.PaperSize = new PaperSize { Width = 58 };
            doc.PrinterSettings.PrintToFile = true;
            doc.PrinterSettings.PrintFileName = "d:\\11.pdf";
           
            doc.PrintPage += (sender, args) =>
            {
                Font titleFont = new Font(FontName, 6.5f, FontStyle.Bold);        

                Brush brush = new SolidBrush(Color.Black);//画刷            

                //Pen pen = new Pen(Color.Black,2f);           //线条颜色            


                //using var img = Image.FromFile(Path.Combine(reportsDirectory, "logo.jpg"));
                //args.Graphics.DrawImage(img, 50, 0, 100, 100);"Ma t/m Za 08:00-20:00Zo10:00-18:00\r\n×4567890123456789"

                Point po = new Point(0, 0);
                args.Graphics.DrawString(text, titleFont, brush, po);   //DrawString方式进行打印。



            };
            doc.EndPrint += (sender, args) =>
            {

            };
            doc.Print();
        }

    }
}
